/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.mall.shopping.web.TuangouAction
   Module Description   :

   Date Created      : 2011/8/22
   Original Author   : feeling.wang
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.mall.shopping.web;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.geronimo.mail.util.Base64;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.yaodian100.core.common.service.BaseManager;
import com.yaodian100.core.common.service.DomainService;
import com.yaodian100.core.common.utils.ServerValue;
import com.yaodian100.core.common.utils.StringUtils;
import com.yaodian100.core.logger.service.LogService;
import com.yaodian100.core.mail.entity.Mail;
import com.yaodian100.core.mail.service.MailService;
import com.yaodian100.core.menu.entity.Menu;
import com.yaodian100.ec.channel.service.ChannelService;
import com.yaodian100.ec.delivery.service.DeliveryRuleService;
import com.yaodian100.ec.member.entity.AddressBook;
import com.yaodian100.ec.member.entity.Member;
import com.yaodian100.ec.member.service.MemberService;
import com.yaodian100.ec.order.entity.Orders;
import com.yaodian100.ec.order.service.TuangouOrderService;
import com.yaodian100.ec.product.entity.DaphneProduct;
import com.yaodian100.ec.product.entity.Product;
import com.yaodian100.ec.product.entity.SpecificationInventory;
import com.yaodian100.ec.product.entity.SpecificationMajor;
import com.yaodian100.ec.product.service.DaphneProductService;
import com.yaodian100.ec.product.service.Product2Service;
import com.yaodian100.ec.shelf.entity.ShelfTuangou;
import com.yaodian100.ec.shelf.service.ShelfTuangouService;
import com.yaodian100.ec.shopping.entity.CartOrderProduct;
import com.yaodian100.ec.shopping.entity.CartOrderProductDetail;
import com.yaodian100.ec.shopping.entity.CartOrders;
import com.yaodian100.ec.shopping.service.CartOrdersService;
import com.yaodian100.mall.member.util.UserData;

/**
 * @author feeling.wang
 * 
 */
public class TuangouOrderAction extends ActionSupport implements Preparable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 4977988790849772033L;
	private final Logger logger = LoggerFactory.getLogger(TuangouOrderAction.class);

	@Autowired
	private ShelfTuangouService shelfTuangouService;
	@Autowired
	private Product2Service product2Service;
	@Autowired
	private DaphneProductService daphneProductService;
	@Autowired
	private DeliveryRuleService deliveryRuleService;
	@Autowired
	private TuangouOrderService tuangouOrderService;
	@Autowired
	private MemberService memberService;
	@Autowired
	private CartOrdersService cartOrdersService;
	@Autowired
	private ChannelService channelService;
	@Autowired
	private BaseManager baseMgr;
	@Autowired
	private LogService logService;
	@Autowired
	private DomainService<Menu> menuService;
	@Autowired
	private MailService mailService;

	// prepare menu
	private Menu paymentTpMenu;
	private Menu rateMenu;
	private Menu bankCodeMenu;
	private Menu paymentSrcMenu;

	// final var
	private final String tuangouMail = "yaotuangou@yaodian100.com";
	private final String tuangouBccMail = "feeling.wang@yaodian100.com";
	private final String contextPath = ServerValue.getFrontContextPath();

	private String orderInfoView = "";
	private Long tuangouId;
	private Product product;
	private boolean resultDaphne;
	private Map<String, String> provincesMap;
	private Map<String, SpecificationInventory> prodInvMap;// 库存
	private List<SpecificationMajor> prodMajors;
	private AddressBook addBookDataJson;

	private List<CartOrderProductDetail> cartOrderProductDetailList;
	private List<CartOrderProduct> cartOrderProductList;

	private CartOrders cartOrders;
	private String actionResult;
	private String paymentInfoResult;
	private Member member;
	private Orders order;
	private String msgType;

	// 前端頁面參數
	private String actMsg;// action的错误讯息
	private ShelfTuangou st;
	private Long[] tuangouSpecId;// 购买规格编号
	private Integer[] tuangouQty;// 购买数量
	private String paytype = "50";// 付款方式
	private String contactName;// 收货人姓名
	private String province = " ";// 省份
	private String city = " ";// 市
	private String district = " ";// 区
	private String zipCode;// 邮编
	private String addr;// 街道
	private String areaCode;// 区码
	private String phone;// 电话
	private String extension;// 分机
	private String mobile;// 手机
	private String editTotalAmount;
	private String finalTotalAmount;
	private String channelResult;
	private String storeId;
	private String bitem;
	private String b100item = "";
	private String mail;
	private String chkVrtBlnc;// 帐户余额
	private String chkGiftCard;// 礼品卡
	private String editShipFare = "";// 运费
	private String ccode;// 验证码
	private String ccodeResult;// 验证码json回传结果
	private String bankCode;// 支付的银行代码
	private String invotype;// 发票信息 01－个人，02－单位
	private String invoTitle;
	private String delivery;// 配送方式　nml：快递，dpn：达芙妮

	private Menu systemValueMenu;// 系统参数

	private Orders orders;
	private String orderId;

	private List<AddressBook> abList;// 地址簿
	private String id;
	private boolean ismobileVaild;// 检核是否做过手机验证

	/**
	 * 团购主页
	 * 
	 * @return
	 * @throws Exception
	 */
	public String orderBuyTuangou() throws Exception {
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		String memberId = StringUtils.defaultString(userData.getMemberId());
		member = (Member) baseMgr.get(Member.class, memberId);
		st = shelfTuangouService.getActiveShelfTuangouByTuangouId(tuangouId);
		boolean canBuyResult = true;
		// 卖场不存在或已过期,导到团购页面
		if (null == st) {
			logger.error("团购编号:" + tuangouId + ",不存在或已过期");
			// Mail mail = new Mail("团购卖场异常通知信：卖场不存在或已过期", "团购编号:" + tuangouId + ",不存在或已过期", tuangouMail, tuangouBccMail);
			// mailService.save(mail);
			msgType = "outSale";
			return "tuangouMsg";
		}
		// 判断团购卖场的型态是否正确
		if (!"1".equals(st.getSalesType())) {
			logger.error("团购编号:" + tuangouId + ",进入商品团购卖场时型态不正确,salesType:" + st.getSalesType());
			Mail mail = new Mail("团购卖场异常通知信：商品团购卖场时型态不正确", "团购编号:" + tuangouId + ",进入商品团购卖场时型态不正确,salesType:"
					+ st.getSalesType(), tuangouMail, tuangouBccMail);
			mailService.save(mail);
			msgType = "outSale";
			return "tuangouMsg";
		}
		// 可售數
		int specInvSum = product2Service.getSpecificationInventorySum(st.getProductId());
		// 判断团购卖场的数量,导到团购页面
		if (st.getOrderQty() < 0 || specInvSum == 0) {
			logger.error("团购商品已售完,团购编号:" + st.getTuangouId() + ",商品编号：" + st.getProductId());
			Mail mail = new Mail("团购卖场异常通知信：商品已售完", "团购编号:" + st.getTuangouId() + ",商品编号：" + st.getProductId(), tuangouMail,
					tuangouBccMail);
			mailService.save(mail);
			msgType = "outSale";
			return "tuangouMsg";
		}
		// 非会员不能参加团购
		if (StringUtils.equals("nonmember", member.getApplySource())) {
			msgType = "outSale";
			return "tuangouMsg";
		}
		// 檢查是否有限定會員只能購買一次
		if (StringUtils.equals("Y", st.getMemberLimit())) {
			canBuyResult = tuangouOrderService.canBuy(tuangouId, memberId);
		}
		if (canBuyResult) {
			// 商品资料
			product = (Product) baseMgr.get(Product.class, st.getProductId());
			prodMajors = product.getActivateSpecMajors();
			prodInvMap = product2Service.getSpecificationInventoryMap(st.getProductId());
			// 地址簿-省
			provincesMap = deliveryRuleService.getProductProvinces(st.getProductId());
			// 判断是否为daphne商品
			DaphneProduct daphneProduct = daphneProductService.getAvailableDaphneProductById(st.getProductId());
			if (null == daphneProduct) {
				resultDaphne = false;
			} else {
				// 判断是否符合门店取货的限制
				if (st.getPrice().compareTo(ServerValue.getDaphneLimitPrice()) != 1) {
					resultDaphne = false;
				} else {
					resultDaphne = true;
				}
			}
		} else {
			logger.error("团购编号:" + st.getTuangouId() + ",限会员只能购买一次");
			// 限会员只能购买一次,导到团购页面
			msgType = "outSale";
			return "tuangouMsg";
		}
		// 检核是否做过手机验证
		ismobileVaild = member.getIsMobileMember();
		return "orderBuyTuangou";
	}

	public String jsonPaymentInfoByTuangou() throws Exception {
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		String memberId = StringUtils.defaultString(userData.getMemberId());
		cartOrders = tuangouOrderService.createTuangouCart(memberId);
		st = shelfTuangouService.getActiveShelfTuangouByTuangouId(tuangouId);
		if (null != st && "1".equals(st.getSalesType())) {// 1表示团购
			if (StringUtils.equals("Y", st.getMemberLimit())) {
				if (!tuangouOrderService.canBuy(tuangouId, memberId)) {
					paymentInfoResult = "qtyNotEnoughTip＠限会员只能购买一次";
					return "jsonPaymentInfoResult";
				}
			}
			// 验证码检核
			if (null != userData.getImageValid() && StringUtils.isNotBlank(userData.getImageValid())) {
				if (StringUtils.isBlank(ccode)) {
					paymentInfoResult = "ccodeTip＠验证码参数错误";
					return "jsonPaymentInfoResult";
				}
				try {
					cartOrdersService.checkCode(userData.getImageValid(), ccode);
				} catch (Exception e) {
					paymentInfoResult = "ccodeTip＠验证码错误，请重新输入";
					return "jsonPaymentInfoResult";
				}
			}
			Product product = (Product) baseMgr.get(Product.class, st.getProductId());
			if (null != product && "N".equals(product.getIsDelete())
					&& Arrays.asList(0, 1, 7).contains(product.getProductType())) {
				// 检查数量
				int i = 0;
				for (Long specId : tuangouSpecId) {
					cartOrders = tuangouOrderService.addTuangouProduct(memberId, cartOrders.getCartId(), st.getProductId(),
							specId, tuangouQty[i]);
					i++;
				}
				if (null == chkVrtBlnc) {// 帐户余额
					chkVrtBlnc = "0.00";
				}
				if (null == chkGiftCard) {// 礼品卡
					chkGiftCard = "0.00";
				}
				try {
					String host = request.getHeader("X-Forwarded-For");
					if (StringUtils.isBlank(host)) {
						host = StringUtils.defaultString(request.getRemoteAddr(), "0.0.0.0");
					} else if (host.length() > 100) {
						host = host.substring(0, 100);
					}

					int chId = 0;
					if (StringUtils.isNotBlank(userData.readValue("ch_id"))) {
						chId = Integer.parseInt(userData.readValue("ch_id"));
					} else {
						chId = channelService.getActivateChannelIdByName(userData.getApplySource()).intValue();
					}
					cartOrders.setChannelSeq(chId);

					// 记录达夫妮门店cookie
					if (delivery.equals("dpn") && StringUtils.isNotBlank(storeId)) {
						// 未滿一定金額無法使用店取貨
						if (cartOrders.getAmount().compareTo(ServerValue.getDaphneLimitPrice()) != 1) {
							paymentInfoResult = "qtyNotEnoughTip＠非常抱歉！本商品不支援门店取货";
							return "jsonPaymentInfoResult";
						}
						userData.writeRawValue("storeId", storeId);
					}
					if (StringUtils.isNotBlank(contactName)) {
						StringBuffer sbReceiver = new StringBuffer();
						sbReceiver.append(StringUtils.defaultString(contactName)).append(",");
						sbReceiver.append(StringUtils.defaultString(areaCode)).append(",");
						sbReceiver.append(StringUtils.defaultString(phone)).append(",");
						sbReceiver.append(StringUtils.defaultString(extension)).append(",");
						sbReceiver.append(StringUtils.defaultString(mobile));
						userData.writeRawValue("receiverData", new String(Base64.encode(sbReceiver.toString().getBytes())));
					}
					// 訂購流程_商品不足之检查
					String invntryInfo = cartOrdersService.checkTuangouSpecInventory(cartOrders.getCartId());
					if (!"OK".equals(invntryInfo)) {
						paymentInfoResult = "qtyNotEnoughTip＠非常抱歉！订单中的个别商品库存不足，下次团购成功后记得尽快提交订单哦！";
						return "jsonPaymentInfoResult";
					}
					cartOrders.setInvoiceTp(invotype);
					cartOrders.setInvoiceTitle(invoTitle);
					orders = pay(cartOrders, host, userData.getApplySource(), StringUtils.defaultString(storeId), st
							.getTuangouId().toString(), st.getPromoteName());
					orderId = orders.getOrderId();
					orderInfoView = orderInfoView + orders.getOrderId() + "&channelFlag=Y";
				} catch (CartException cartError) {
					paymentInfoResult = cartError.toString();
					return "jsonPaymentInfoResult";
				} catch (Exception e) {
					e.printStackTrace();
					paymentInfoResult = "qtyNotEnoughTip＠非常抱歉！订单中的个别商品库存不足，下次团购成功后记得尽快提交订单哦！";
					return "jsonPaymentInfoResult";
				}
				logger.info("orders:{}", orders.getOrderId());
				if (null != orders) {
					logService.save(getClass().getSimpleName(), "paymentInfo", orders);
					// 导到付款页面
					if ("50".equals(orders.getPaymentTp())) {
						if (Arrays.asList("alipay", "quickmoney", "tenpay", "chinapay").contains(bankCode)) {// 第三方支付
							if ("alipay".equals(bankCode)) {
								orderInfoView = contextPath + "/payment/alipay.do?orderId=" + orders.getPaymentTxnId()
										+ "&paymentType=direct";
							}
							if ("quickmoney".equals(bankCode)) {
								orderInfoView = contextPath + "/payment/quickmoney.do?orderId=" + orders.getPaymentTxnId();
							}
							if ("tenpay".equals(bankCode)) {
								orderInfoView = contextPath + "/payment/tenpay.do?orderId=" + orders.getPaymentTxnId();
							}
							if ("chinapay".equals(bankCode)) {
								orderInfoView = contextPath + "/payment/chinapay.do?orderId=" + orders.getPaymentTxnId();
							}
						} else {// 银行
							orderInfoView = contextPath
									+ paymentSrcMenu.getOptions().get(bankCodeMenu.getOptions().get(bankCode).getMemo1()).getMemo1()
									+ orders.getPaymentTxnId() + "&bankCode=" + bankCode;
						}
					}
					if ("70".equals(orders.getPaymentTp())) {
						orderInfoView = contextPath + "/payment/quickmoneyCC.do?orderId=" + orders.getOrderId() + "&period=1";
					}
					if ("40".equals(orders.getPaymentTp())) {
						orderInfoView = contextPath + "/shopping/tuangou/tuangouMsg.do?msgType=order&orderId="
								+ orders.getOrderId();
					}
					logger.info("orderInfoView:{}", orderInfoView);
					// return "paymentInfoByTuangou";
					paymentInfoResult = "ok＠" + orderInfoView;
					return "jsonPaymentInfoResult";
				}
			} else {
				Mail mail = new Mail("团购卖场异常通知信：商品已下架", "商品编号:" + st.getProductId() + "已下架", tuangouMail, tuangouBccMail);
				mailService.save(mail);
				paymentInfoResult = "qtyNotEnoughTip＠非常抱歉！团购卖场商品已下架";
				return "jsonPaymentInfoResult";
			}
		} else {
			paymentInfoResult = "qtyNotEnoughTip＠团购卖场已过期或型态不正确";
			return "jsonPaymentInfoResult";
		}
		return "jsonPaymentInfoResult";
	}

	public String tuangouMsg() {
		if (StringUtils.equalsIgnoreCase("order", msgType)) {// 订单成立讯息
			if (StringUtils.isNotBlank(orderId) && StringUtils.length(orderId) == 13 && NumberUtils.isNumber(orderId)) {
				order = (Orders) baseMgr.get(Orders.class, orderId);
				// if (null != order) {
				// st = shelfTuangouService.get(order.getTuangouId());
				// }
			}
		} else if (StringUtils.equalsIgnoreCase("outSale", msgType)) {// 查无商品/无团购讯息

		}
		return "tuangouMsg";
	}

	public void prepare() throws Exception {
		if (null == paymentTpMenu) {
			paymentTpMenu = menuService.get("Order.PaymentTp");
		}
		if (null == rateMenu) {
			rateMenu = menuService.get("Fanli.Rate");
		}
		if (null == bankCodeMenu) {
			bankCodeMenu = menuService.get("Payment.3rdPartyBank");
		}
		if (null == paymentSrcMenu) {
			paymentSrcMenu = menuService.get("Payment.Src");
		}
		if (null == systemValueMenu) {
			systemValueMenu = menuService.get("SystemValue");
		}
	}

	private Orders pay(CartOrders cartOrders, String host, String channel, String storeId, String tuangouId,
			String tuangouName) throws Exception {
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		Map<String, String> addonInfo = new HashMap<String, String>();
		addonInfo.put("remoteAddr", host);
		addonInfo.put("applySource", channel);
		addonInfo.put("domain", request.getServerName());
		addonInfo.put("channelChild", userData.getChChildCookie());
		addonInfo.put("storeId", storeId);

		String userAgent = request.getHeader("User-Agent");
		String bcookie = request.getHeader("Cookie");
		Map<String, String> requestMap = request.getParameterMap();
		addonInfo.put("userAgent", userAgent);
		addonInfo.put("bcookie", bcookie);
		addonInfo.put("requestMap", JSONUtil.serialize(requestMap));
		addonInfo.put("tuangouId", tuangouId);
		addonInfo.put("tuangouName", tuangouName);
		String thisVal = "";
		if (StringUtils.isNotBlank(delivery)) {
			if ("dpn".equals(delivery)) {
				thisVal = delivery + "_";
			}
		}

		cartOrders.setChannel(channel);
		if (StringUtils.length(addr) > 100) {
			addr = StringUtils.substring(addr, 0, 100);
		}
		if (true == tuangouOrderService.isInteger2(addr)) {
			throw new CartException(thisVal + "addrTip＠不允许全部数字输入！");
		}
		cartOrders.setReceiverAddr(addr);
		if (StringUtils.contains(district, "※")) {
			district = district.split(",")[0].substring(1);
		} else {
			district = district.split(",")[0];
		}
		cartOrders.setReceiverArea(district);
		cartOrders.setReceiverCity(city);
		cartOrders.setReceiverExt(extension);
		cartOrders.setReceiverMobile(mobile);

		if (true == tuangouOrderService.isInteger(contactName)) {
			throw new CartException(thisVal + "contactNameTip＠不允许数字输入！");
		}

		cartOrders.setReceiverName(contactName);
		cartOrders.setReceiverPhone(phone);
		cartOrders.setReceiverPhoneArea(areaCode);
		cartOrders.setReceiverProvince(province);
		if (StringUtils.length(zipCode) > 6) {
			zipCode = StringUtils.substring(zipCode, 0, 6);
		}
		cartOrders.setReceiverZip(zipCode);
		String memberId = StringUtils.defaultString(userData.getMemberId());
		Member member = memberService.get(memberId);
		if ("xx".equals(member.getSendEmail())) {
			cartOrders.setReceiverEmail(mail);
		}
		Map<String, String> payment = new HashMap<String, String>();
		payment.put("paymentType", paytype);
		payment.put("vrtBlnc", chkVrtBlnc);
		payment.put("giftCard", chkGiftCard);

		if ("02".equals(cartOrders.getInvoiceTp())) {
			payment.put("invotype", cartOrders.getInvoiceTp());
			payment.put("invoTitle", cartOrders.getInvoiceTitle());
		}
		// 订单成立时应只允许isDelete = 'N'才能写入订单。
		Product productN = null;
		for (CartOrderProduct cartOrderProd : cartOrders.getCartOrderProducts()) {
			productN = (Product) baseMgr.get(Product.class, cartOrderProd.getProdId());
			if (!"N".equalsIgnoreCase(productN.getIsDelete())) {
				logger.error("商品销售状态不符, cartId:{}, cart product:{}, product:{}", new Object[] { cartOrders.getCartId(),
						cartOrderProd, productN });
				throw new CartException("qtyNotEnoughTip＠商品销售状态不符！");
			}
		}
		BigDecimal amountFromPage = new BigDecimal(editTotalAmount).setScale(1);
		BigDecimal cartSumAmount = cartOrders.getAmount();
		// 帐户馀额检查chkVrtBlnc
		if (new BigDecimal(chkVrtBlnc).compareTo(member.getBalance().getVirtualBalance()) == 1) {
			logger.error("cart.id:{}, 我的帐户余额>实际我的帐户余额,chkVrtBlnc:{}, memberVirtualBalance: {}", new Object[] {
					cartOrders.getCartId(), chkVrtBlnc, member.getBalance().getVirtualBalance() });
			throw new CartException("qtyNotEnoughTip＠我的帐户余额>实际我的帐户余额！");
		}
		// 礼品卡馀额检查chkGiftCard
		if (new BigDecimal(chkGiftCard).compareTo(member.getBalance().getGiftcardBalance()) == 1) {
			logger.error("cart.id:{}, 我的礼品卡余额>实际我的礼品卡余额,chkGiftCard:{}, memberGiftcardBalance: {}", new Object[] {
					cartOrders.getCartId(), chkGiftCard, member.getBalance().getGiftcardBalance() });
			throw new CartException("qtyNotEnoughTip＠我的礼品卡余额>实际我的帐户余额！");
		}
		// 剩余应付金额不可为负值
		if (new BigDecimal(finalTotalAmount).compareTo(BigDecimal.ZERO) == -1) {
			logger.error("cart.id:{}, 剩余应付金额<,finalTotalAmount:{}", finalTotalAmount);
			throw new CartException("qtyNotEnoughTip＠剩余应付金额<0！");
		}
		if (cartOrders.getCartOrderProducts() == null || cartOrders.getCartOrderProducts().size() == 0
				|| Math.abs(cartSumAmount.subtract(amountFromPage).floatValue()) != 0) {
			logger.error("cart:{}, cart products:{}, cart.sum:{}, amountFromPage:{}", new Object[] { cartOrders,
					cartOrders.getCartOrderProducts(), cartSumAmount, amountFromPage });
			throw new CartException("qtyNotEnoughTip＠订单金额与预期不符！");
		}

		Orders result = null;
		boolean retry = true;
		int count = 0;
		do {
			try {
				count++;
				result = tuangouOrderService.createTuangouOrderWithPay(cartOrders, addonInfo, payment);
				retry = false;
			} catch (Exception e) {
				logger.error("fail " + count + " times, cart:" + cartOrders, e);
				Thread.sleep(100);
				CartOrders tmp = tuangouOrderService.getTuangouCartOrders(cartOrders.getMemberId(), cartOrders.getCartId());
				if (tmp == null || !tmp.getModifyDate().equals(cartOrders.getModifyDate())
						|| "error.coupon.isused".equals(e.getMessage())) {
					cartOrdersService.delete(cartOrders);
					throw new CartException("qtyNotEnoughTip＠订单已经建立，请检查最近订单明细！");
				} else if ("errors.order.address.not.match".equals(e.getMessage())) {
					throw new CartException("qtyNotEnoughTip＠地址资料不符合！");
				} else if ("errors.order.badman".equals(e.getMessage())) {
					throw new CartException("qtyNotEnoughTip＠您的帐号异常, 请洽客服人员");
				} else if (e.getMessage() != null
						&& (e.getMessage().startsWith("error.coupon.") || e.getMessage().startsWith("error.order.") || e
								.getMessage().startsWith("error.payment."))) {
					// 丟這幾個開頭, 都是資料異常, 可以考慮丟到黑名單
					throw new CartException("qtyNotEnoughTip＠订单建立失败！");
				} else if (count > 4) {
					throw new CartException("qtyNotEnoughTip＠订单建立失败！");
				}
			}
		} while (retry);
		return result;
	}

	public String jsonChkValidateNum() throws Exception {
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		try {
			ccodeResult = "";
			cartOrdersService.checkCode(userData.getImageValid(), ccode);
			ccodeResult = "ok";
		} catch (Exception e) {
			ccodeResult = "error";
		}
		return "jsonChkValidateNum";
	}

	// 从收货地址簿选取
	public String loadMyAddBook() throws Exception {
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		Map<String, String> drMap = deliveryRuleService.findDeliveryType("product", id);
		String deliveryType = drMap.get("deliveryType");
		if (StringUtils.equalsIgnoreCase(ServerValue.getScmType(), deliveryType)) {
			abList = memberService.getCanUseAddressBook(userData.getMemberId(), deliveryType, drMap.get("fromProvince"),
					drMap.get("fromCity"), drMap.get("fromDistrict"));
		} else {
			// 大材积
			if (product2Service.chkVolumeOfProduct(id)) {
				abList = memberService.getCanUseAddressBook(userData.getMemberId(), deliveryType, "", "", "", true);
			} else {
				abList = memberService.getCanUseAddressBook(userData.getMemberId(), deliveryType, "", "", "");
			}
		}
		return "myAddBook";
	}

	/**
	 * 查询最新收货地址
	 * 
	 * @return
	 * @throws Exception
	 */
	public String findLastAddBook() throws Exception {
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		UserData userData = new UserData(request, response);
		String memberId = StringUtils.defaultString(userData.getMemberId());
		Member member = memberService.get(memberId);

		Map<String, String> drMap = deliveryRuleService.findDeliveryType("product", id);
		String deliveryType = drMap.get("deliveryType");
		if (StringUtils.equalsIgnoreCase(ServerValue.getScmType(), deliveryType)) {
			abList = memberService.getCanUseAddressBook(member.getMemberId(), deliveryType, drMap.get("fromProvince"), drMap
					.get("fromCity"), drMap.get("fromDistrict"));
		} else {
			// 大材积
			if (product2Service.chkVolumeOfProduct(id)) {
				abList = memberService.getCanUseAddressBook(member.getMemberId(), deliveryType, "", "", "", true);
			} else {
				abList = memberService.getCanUseAddressBook(member.getMemberId(), deliveryType, "", "", "");
			}
		}
		if (abList.size() > 0) {
			addBookDataJson = abList.get(0);
			setContactName(addBookDataJson.getContactName());
			setCity(addBookDataJson.getCity());
			setDistrict(addBookDataJson.getDistrict());
			setProvince(addBookDataJson.getProvince());
		}
		return "jsonGetAddBook";
	}

	public Long getTuangouId() {
		return tuangouId;
	}

	public void setTuangouId(Long tuangouId) {
		this.tuangouId = tuangouId;
	}

	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}

	public boolean isResultDaphne() {
		return resultDaphne;
	}

	public void setResultDaphne(boolean resultDaphne) {
		this.resultDaphne = resultDaphne;
	}

	public Map<String, String> getProvincesMap() {
		return provincesMap;
	}

	public void setProvincesMap(Map<String, String> provincesMap) {
		this.provincesMap = provincesMap;
	}

	public Map<String, SpecificationInventory> getProdInvMap() {
		return prodInvMap;
	}

	public void setProdInvMap(Map<String, SpecificationInventory> prodInvMap) {
		this.prodInvMap = prodInvMap;
	}

	public List<SpecificationMajor> getProdMajors() {
		return prodMajors;
	}

	public void setProdMajors(List<SpecificationMajor> prodMajors) {
		this.prodMajors = prodMajors;
	}

	public CartOrders getCartOrders() {
		return cartOrders;
	}

	public void setCartOrders(CartOrders cartOrders) {
		this.cartOrders = cartOrders;
	}

	public String getActionResult() {
		return actionResult;
	}

	public void setActionResult(String actionResult) {
		this.actionResult = actionResult;
	}

	public String getStoreId() {
		return storeId;
	}

	public String getPaytype() {
		return paytype;
	}

	public String getContactName() {
		return contactName;
	}

	public String getProvince() {
		return province;
	}

	public String getCity() {
		return city;
	}

	public String getDistrict() {
		return district;
	}

	public String getZipCode() {
		return zipCode;
	}

	public String getAddr() {
		return addr;
	}

	public String getAreaCode() {
		return areaCode;
	}

	public String getPhone() {
		return phone;
	}

	public String getExtension() {
		return extension;
	}

	public String getMobile() {
		return mobile;
	}

	public void setStoreId(String storeId) {
		this.storeId = storeId;
	}

	public void setPaytype(String paytype) {
		this.paytype = paytype;
	}

	public void setContactName(String contactName) {
		this.contactName = contactName;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public void setDistrict(String district) {
		this.district = district;
	}

	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}

	public void setAddr(String addr) {
		this.addr = addr;
	}

	public void setAreaCode(String areaCode) {
		this.areaCode = areaCode;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public void setExtension(String extension) {
		this.extension = extension;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public String getFinalTotalAmount() {
		return finalTotalAmount;
	}

	public String getChannelResult() {
		return channelResult;
	}

	public String getBitem() {
		return bitem;
	}

	public String getB100item() {
		return b100item;
	}

	public String getMail() {
		return mail;
	}

	public void setFinalTotalAmount(String finalTotalAmount) {
		this.finalTotalAmount = finalTotalAmount;
	}

	public void setChannelResult(String channelResult) {
		this.channelResult = channelResult;
	}

	public void setBitem(String bitem) {
		this.bitem = bitem;
	}

	public void setB100item(String b100item) {
		this.b100item = b100item;
	}

	public void setMail(String mail) {
		this.mail = mail;
	}

	public String getChkVrtBlnc() {
		return chkVrtBlnc;
	}

	public String getEditShipFare() {
		return editShipFare;
	}

	public void setChkVrtBlnc(String chkVrtBlnc) {
		this.chkVrtBlnc = chkVrtBlnc;
	}

	public void setEditShipFare(String editShipFare) {
		this.editShipFare = editShipFare;
	}

	public String getCcode() {
		return ccode;
	}

	public String getInvotype() {
		return invotype;
	}

	public String getInvoTitle() {
		return invoTitle;
	}

	public void setCcode(String ccode) {
		this.ccode = ccode;
	}

	public void setInvotype(String invotype) {
		this.invotype = invotype;
	}

	public void setInvoTitle(String invoTitle) {
		this.invoTitle = invoTitle;
	}

	public List<CartOrderProductDetail> getCartOrderProductDetailList() {
		return cartOrderProductDetailList;
	}

	public List<CartOrderProduct> getCartOrderProductList() {
		return cartOrderProductList;
	}

	public void setCartOrderProductDetailList(List<CartOrderProductDetail> cartOrderProductDetailList) {
		this.cartOrderProductDetailList = cartOrderProductDetailList;
	}

	public void setCartOrderProductList(List<CartOrderProduct> cartOrderProductList) {
		this.cartOrderProductList = cartOrderProductList;
	}

	public Orders getOrders() {
		return orders;
	}

	public String getOrderId() {
		return orderId;
	}

	public void setOrders(Orders orders) {
		this.orders = orders;
	}

	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}

	public String getOrderInfoView() {
		return orderInfoView;
	}

	public void setOrderInfoView(String orderInfoView) {
		this.orderInfoView = orderInfoView;
	}

	public String getEditTotalAmount() {
		return editTotalAmount;
	}

	public void setEditTotalAmount(String editTotalAmount) {
		this.editTotalAmount = editTotalAmount;
	}

	public Long[] getTuangouSpecId() {
		return tuangouSpecId;
	}

	public void setTuangouSpecId(Long[] tuangouSpecId) {
		this.tuangouSpecId = tuangouSpecId;
	}

	public ShelfTuangou getSt() {
		return st;
	}

	public void setSt(ShelfTuangou st) {
		this.st = st;
	}

	public Integer[] getTuangouQty() {
		return tuangouQty;
	}

	public void setTuangouQty(Integer[] tuangouQty) {
		this.tuangouQty = tuangouQty;
	}

	public Menu getPaymentTpMenu() {
		return paymentTpMenu;
	}

	public Menu getRateMenu() {
		return rateMenu;
	}

	public Menu getBankCodeMenu() {
		return bankCodeMenu;
	}

	public Menu getPaymentSrcMenu() {
		return paymentSrcMenu;
	}

	public void setPaymentTpMenu(Menu paymentTpMenu) {
		this.paymentTpMenu = paymentTpMenu;
	}

	public void setRateMenu(Menu rateMenu) {
		this.rateMenu = rateMenu;
	}

	public void setBankCodeMenu(Menu bankCodeMenu) {
		this.bankCodeMenu = bankCodeMenu;
	}

	public void setPaymentSrcMenu(Menu paymentSrcMenu) {
		this.paymentSrcMenu = paymentSrcMenu;
	}

	public String getBankCode() {
		return bankCode;
	}

	public void setBankCode(String bankCode) {
		this.bankCode = bankCode;
	}

	public String getCcodeResult() {
		return ccodeResult;
	}

	public void setCcodeResult(String ccodeResult) {
		this.ccodeResult = ccodeResult;
	}

	public String getActMsg() {
		return actMsg;
	}

	public void setActMsg(String actMsg) {
		this.actMsg = actMsg;
	}

	public List<AddressBook> getAbList() {
		return abList;
	}

	public String getId() {
		return id;
	}

	public void setAbList(List<AddressBook> abList) {
		this.abList = abList;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPaymentInfoResult() {
		return paymentInfoResult;
	}

	public void setPaymentInfoResult(String paymentInfoResult) {
		this.paymentInfoResult = paymentInfoResult;
	}

	public String getDelivery() {
		return delivery;
	}

	public void setDelivery(String delivery) {
		this.delivery = delivery;
	}

	public Member getMember() {
		return member;
	}

	public void setMember(Member member) {
		this.member = member;
	}

	public AddressBook getAddBookDataJson() {
		return addBookDataJson;
	}

	public void setAddBookDataJson(AddressBook addBookDataJson) {
		this.addBookDataJson = addBookDataJson;
	}

	public Orders getOrder() {
		return order;
	}

	public void setOrder(Orders order) {
		this.order = order;
	}

	public String getMsgType() {
		return msgType;
	}

	public void setMsgType(String msgType) {
		this.msgType = msgType;
	}

	public boolean isIsmobileVaild() {
		return ismobileVaild;
	}

	public void setIsmobileVaild(boolean ismobileVaild) {
		this.ismobileVaild = ismobileVaild;
	}

	public String getChkGiftCard() {
		return chkGiftCard;
	}

	public void setChkGiftCard(String chkGiftCard) {
		this.chkGiftCard = chkGiftCard;
	}
}